package nancal.mp.mvc.dev

import io.swagger.annotations.*
import nancal.mp.db.mongo.*
import nancal.mp.db.mongo.entity.*
import nancal.mp.db.mongo.entity.dev.*
import nbcp.base.annotation.*
import nbcp.base.annotation.mvc.*
import nbcp.base.comm.*
import nbcp.base.extend.*
import nbcp.base.model.HttpInvoke
import nbcp.mvc.sys.*
import nbcp.myoql.db.*
import nbcp.myoql.db.mongo.*
import nbcp.web.*

import org.springframework.data.mongodb.core.query.*
import org.springframework.web.bind.annotation.*
import java.time.*
import javax.servlet.http.*

/**
 * Created by CodeGenerator at 2024-03-01 22:26:42
 */
@Api(description = "Api测试", tags = arrayOf("ApiExecTest"))
@RestController
@RequestMapping("/dev/api-exec-test")
class ApiExecTestAutoController {

    @ApiOperation("列表")
    @PostMapping("/list")
    fun list(
        id: String, //当列表列新一条后，刷新时使用
        @org.springframework.web.bind.annotation.RequestBody query: PagerModel<Any?>,
        request: HttpServletRequest
    ): ListResult<ApiExecTest> {

        mor.dev.apiExecTest.query()
            .apply {
                if (id.HasValue) {
                    this.where { it.id mongoEquals id }
                }
            }
            .withPager(query)
            .toListResult()
            .apply {
                return this;
            }
    }

    @ApiOperation("详情")
    @PostMapping("/detail/{id}")
    fun detail(
        @Require id: String,
        request: HttpServletRequest
    ): ApiResult<ApiExecTest> {
        mor.dev.apiExecTest.queryById(id)
            .toEntity()
            .apply {
                if (this == null) {
                    return ApiResult.error("找不到数据")
                }

                return ApiResult.of(this)
            }
    }

    @ApiOperation("更新")
    @PostMapping("/save")
    fun save(
        @org.springframework.web.bind.annotation.RequestBody entity: ApiExecTest,
        request: HttpServletRequest
    ): ApiResult<String> {
        //鉴权
        var userId = request.UserId;

        mor.dev.apiExecTest.updateWithEntity(entity)
            .withColumns(request.requestParameterKeys)
            .run {
                if (entity.id.HasValue) {
                    return@run this.execUpdate()
                } else {
                    return@run this.execInsert()
                }
            }
            .apply {
                if (this == 0) {
                    return ApiResult.error("更新失败")
                }

                return ApiResult.of(entity.id)
            }
    }

    @ApiOperation("删除")
    @PostMapping("/delete/{id}")
    fun delete(
        @Require id: String,
        request: HttpServletRequest
    ): JsonResult {
        //鉴权
        var userId = request.UserId

        var entity = mor.dev.apiExecTest.queryById(id).toEntity()
        if (entity == null) {
            return JsonResult.error("找不到数据")
        }

        mor.dev.apiExecTest.deleteById(id)
            .exec()
            .apply {
                if (this == 0) {
                    return JsonResult.error("删除失败")
                }
                //实体上配置垃圾箱功能，可物理删除，会自动移到垃圾箱。
                return JsonResult()
            }
    }


    @ApiOperation("删除")
    @PostMapping("/latest/{apiDefineId}")
    fun latest(
        @Require apiDefineId: String,
        request: HttpServletRequest
    ): ApiResult<ApiExecTest> {
        //鉴权
        var userId = request.UserId

        var entity = mor.dev.apiExecTest.query()
            .where { it.apiDefine.id mongoEquals apiDefineId }
            .toEntity()
        return ApiResult.of(entity);
    }


    class ExecApiRequestModel {
        var apiDefineId = ""
        var host = ""
        var authorization = ""
        var parameters = JsonMap()
    }

    @ApiOperation("exec-api")
    @PostMapping("/exec-api")
    fun execApi(
        @org.springframework.web.bind.annotation.RequestBody model: ExecApiRequestModel
    ): ApiResult<ApiExecTest> {
        var define = mor.dev.apiDefine.queryById(model.apiDefineId).toEntity();
        if (define == null) {
            throw RuntimeException("找不到Api");
        }

        var url = model.host;
        if (!url.startsWith("http://") && !url.startsWith("https://")) {
            url = "http://" + url;
        }
        url += define.url.formatWithJson({ it, _ ->
            model.parameters.get(it).AsString()
        })


        var test = ApiExecTest();
        test.apiDefine = define
        test.host = model.host
        test.authorization = model.authorization;
        test.parameters = StringMap(
            *model.parameters
                .filter { it.value != null && it.value!!.javaClass.IsSimpleType() }
                .map { it.key to it.value.toString() }
                .toTypedArray()
        )

        var http = HttpInvoke();
        http.url = url;
        http.postObject = test.parameters;
        if (define.requestHeaderParameters.HasValue) {
            var headerJson = StringMap();
            define.requestHeaderParameters.forEach {
                var v = model.parameters[it.key];
                if (v == null) {
                    return@forEach
                }

                headerJson.put(it.key, model.parameters[it.key].AsString());
            }

            http.requestHeader.putAll(headerJson);
        }

        if (model.authorization.HasValue) {
            http.requestHeader.put("authorization", "Bearer " + model.authorization);
        }

        http.requestMethod = define.httpMethod.name

        var resp = http.doInvoke();
        if (resp == null) {
            return ApiResult.error("网络错误")
        }





        test.status = resp.status
        resp.responseHeader.keys.forEach {
            test.responseHeader.put(it, resp.responseHeader.get(it).AsString())
        }
        test.responseBody = resp.responseText.AsString()

        mor.dev.apiExecTest.doInsert(test)

        if (resp.status > 0) {
            return ApiResult.of(test);
        }

        return ApiResult.error("网络错误")
    }


}